package com.xjy.rpc.netty.server;

import com.xjy.rpc.netty.handler.server.ServerMessageHandler;
import com.xjy.rpc.netty.handler.RpcDecoder;
import com.xjy.rpc.netty.handler.RpcEncoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

import java.net.InetAddress;
import java.net.UnknownHostException;
@Slf4j
public class ServerTest {
    public static void main(String[] args) {
        ServerTest serverTest = new ServerTest("127.0.0.1",8083);
        serverTest.run();
    }

    private final String serviceType = "req";

    private String ip;

    {
        try {
            ip = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            //这里应该抛出异常
            ip = "127.0.0.1";
            log.debug("本地实际ip获取失败，设置为回环地址");
        }
    }

    @Value("${socket.port}")
    private Integer port;

    private Channel channel;

    public ServerTest(String ip,Integer port){
        this.ip = ip;
        this.port = port;
    }

    public ServerTest(){}

    private NioEventLoopGroup boss;
    private NioEventLoopGroup worker;

    public void run(){
        ServerBootstrap sbs = new ServerBootstrap();
        boss = new NioEventLoopGroup(2);
        worker = new NioEventLoopGroup(5);

        ChannelFuture channelFuture = sbs.group(boss, worker)
                .channel(NioServerSocketChannel.class)
                //设置端口复用
                .option(ChannelOption.SO_REUSEADDR, true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel channel) throws Exception {
                        ChannelPipeline pipeline = channel.pipeline();
                        pipeline.addLast(new RpcEncoder());
                        pipeline.addLast(new RpcDecoder());
                        //执行方法
                        pipeline.addLast(new ServerMessageHandler());
                    }
                })
                .bind(ip, port);

        try {
            channelFuture.sync();
            channel = channelFuture.channel();
            //本地缓存channel  key : req/127.0.0.1/8083 value: channel
            log.info("socket ip:{},port:{},启动成功",ip,port);
            channel.closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            shutdown();
        }
    }

    //@PreDestroy
    public void shutdown(){
        if (boss != null) boss.shutdownGracefully();
        if (worker != null) boss.shutdownGracefully();
        log.info("ip:{},port:{},socket线程资源释放结束",ip,port);
    }
}
